<?php

/**
 * Abstraction pour les classes prenant en charge les elements de type [variable]
 *
 * @category   McCube
 * @package    Template.Parser
 * @author     Leiha Sellier <leiha.sellier@gmail.com>
 * @license    http://creativecommons.org/licenses/by/3.0/  CC BY 3.0
 * @link       http://code.google.com/p/mechanics-cubes/
 */
abstract class McCube_Template_Parser_Element_Variable_Abstract
    extends    McCube_Template_Parser_Element_Abstract
    implements McCube_Template_Parser_Element_Variable_Interface{

    public function execution($helper, $inTag='', $filters=''){
        return $this->_addExecListener(
             $this->build($helper, $inTag, $filters)
        );
    }

    /**
     *
     *
     * @param string $string
     * @return string
     */
    public function buildPhpTag($string){
        return parent::buildPhpTag('echo '.$string.';');
    }

    /**
     *
     *
     * @param string $string
     * @param string $filters
     * @return string
     */
    protected function _applyFilters($string, $filters){
        $filters = explode('|', $filters);
        foreach($filters as $filter){
            if(!$filter = trim($filter))
                continue;

            $string = $this->_applyFilter($string, $filter);
        }
        return $string;
    }

    /**
     *
     *
     * @param string $string
     * @param string $filter
     * @return string
     */
    protected function _applyFilter($string, $filter){
        $params = explode(',', $filter);
        $filter = array_shift($params);

        return call_user_func(
              array('McCube_Template_Parser_Filter_'.ucfirst($filter), 'build')
            , $string
            , $params
        );
    }

    /**
     *
     *
     * @param string $pattern
     * @param string $callback
     * @param string $string
     * @return string
     */
    protected function _parse($pattern, $callback, $string){
        return preg_replace_callback(
              '~'.$pattern.'~'
            , array($this, $callback)
            , $string
        );
    }

    /**
     *
     *
     * @param string $string
     * @param string $char
     * @return string
     */
    protected function _stripSlashes($string, $char){
        return str_replace(
              '\\'.$char
            , $char
            , $string
        );
    }

    /**
     *
     *
     * @param string $variable
     * @param string $inTag
     * @return string
     */
    protected function _buildCallbackForArrayIndex($matches){
        if($matches[1][0] == '$')
            return '['.$matches[1].']';

        $ret = $this->_stripSlashes($matches[1], ']');
        return '[\''.addslashes($ret).'\']';
    }

    /**
     *
     *
     * @param array $matches
     * @return string
     */
    protected function _buildCallbackForMethodArg($matches){
        $args = preg_split('~(?<!\\\),~', $matches[1]);
        foreach($args as &$arg){
            if(!empty($arg) && $arg[0] != '$')
                $arg = '\''.trim($arg).'\'';
        }
        return '('.implode(', ', $args).')';
    }
}